package com.cloud.common.support;

import com.cloud.common.bean.SessionInfo;
import com.cloud.common.context.SessionContext;
import com.cloud.common.sentinel.Sentinel;
import com.cloud.common.util.TokenUtils;
import com.cloud.common.validator.ValidatorHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 会话缓存
 *
 * @author fengwenjin
 */
@Sentinel
@Component
@ConditionalOnClass(RedisTemplate.class)
@ConditionalOnMissingClass("com.cloud.gateway.bean.GatewayInfo")
public class SessionCache {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private ValidatorHelper validatorHelper;

    /**
     * 保存会话
     *
     * @param sessionInfo
     * @param validSeconds
     * @return token
     */
    public String save(SessionInfo sessionInfo, int validSeconds) {
        String errorMsg = validatorHelper.validate(sessionInfo);
        if (StringUtils.isNotEmpty(errorMsg)) {
            throw new RuntimeException(errorMsg);
        }
        sessionInfo.setValidSeconds(validSeconds);
        sessionInfo.setRefreshTime(System.currentTimeMillis());

        String key = getKey(sessionInfo.getAppName(), sessionInfo.getUserId());
        redisTemplate.opsForValue().set(key, sessionInfo, validSeconds, TimeUnit.SECONDS);
        return TokenUtils.build(sessionInfo.getAppName(), sessionInfo.getUserId(), sessionInfo.getSecret());
    }

    /**
     * 获取会话
     *
     * @param appName
     * @param userId
     * @return SessionInfo
     */
    public SessionInfo get(String appName, String userId) {
        String key = getKey(appName, userId);
        return (SessionInfo) redisTemplate.opsForValue().get(key);
    }

    /**
     * 删除会话
     *
     * @param appName
     * @param userId
     */
    public void remove(String appName, String userId) {
        String key = getKey(appName, userId);
        redisTemplate.delete(key);
    }

    private String getKey(String appName, String userId) {
        return SessionContext.SESSION_INFO + ":" + appName + ":" + userId;
    }
}
